package edu.uta.futureye.test;

import java.util.HashMap;

import edu.uta.futureye.algebra.intf.Matrix;
import edu.uta.futureye.algebra.intf.SparseMatrix;
import edu.uta.futureye.algebra.intf.Vector;
import edu.uta.futureye.algebra.solver.Solver;
import edu.uta.futureye.algebra.solver.external.SolverJBLAS;
import edu.uta.futureye.core.Mesh;
import edu.uta.futureye.core.NodeType;
import edu.uta.futureye.function.basic.FX;
import edu.uta.futureye.function.intf.MathFunc;
import edu.uta.futureye.io.MeshReader;
import edu.uta.futureye.io.MeshReaderForTriangle;
import edu.uta.futureye.io.MeshWriter;
import edu.uta.futureye.lib.assembler.AssemblerScalar;
import edu.uta.futureye.lib.element.FELinearTriangle;
import edu.uta.futureye.lib.weakform.WeakFormLaplace2D;
import edu.uta.futureye.tutorial.Tools;
import edu.uta.futureye.util.container.ElementList;
import static edu.uta.futureye.function.FMath.*;

public class Hand {
	public Mesh mesh;
	public Vector u;
	public void run() {
        //1.Read in a triangle mesh from an input file with
        //  format ASCII UCD generated by Gridgen
		//MeshReaderForTriangle reader = new MeshReaderForTriangle("./iphone/hand1.1.node","./iphone/hand1.1.ele");
		//MeshReaderForTriangle reader = new MeshReaderForTriangle("./iphone/hand2.1.node","./iphone/hand2.1.ele");
		MeshReaderForTriangle reader = new MeshReaderForTriangle("./iphone/car2.1.node","./iphone/car2.1.ele");
        Mesh mesh = reader.read2DMesh();
        //Compute geometry relationship of nodes and elements
        mesh.deleteIsolatedNode();
        mesh.computeNodeBelongsToElements();

        //2.Mark border types
        HashMap<NodeType, MathFunc> mapNTF =
                new HashMap<NodeType, MathFunc>();
        mapNTF.put(NodeType.Dirichlet, null);
        mesh.markBorderNode(mapNTF);
        mesh.writeNodesInfo("./iphone/nodeInfo.dat");

        //3.Use element library to assign degrees of
        //  freedom (DOF) to element
        ElementList eList = mesh.getElementList();
        FELinearTriangle feLT = new FELinearTriangle();
        for(int i=1;i<=eList.size();i++)
            feLT.assignTo(eList.at(i));

        //4.Weak form
        WeakFormLaplace2D weakForm = new WeakFormLaplace2D();
        //Right hand side(RHS): f = (x^2+y^2)
        //weakForm.setF(X.M(X).A(Y.M(Y)));
        weakForm.setF(C1);

        //5.Assembly process
        AssemblerScalar assembler =
                new AssemblerScalar(mesh, weakForm);
        assembler.assemble();
        SparseMatrix stiff = assembler.getStiffnessMatrix();
        Vector load = assembler.getLoadVector();
        //Boundary condition
        assembler.imposeDirichletCondition(C0);

        //6.Solve linear system
        Solver solver = new Solver();
        Vector u = solver.solveCG(stiff, load);
        System.out.println("u=");
        for(int i=1;i<=u.getDim();i++)
            System.out.println(String.format("%.3f", u.get(i)));

        //7.Output results to an Techplot format file
        MeshWriter writer = new MeshWriter(mesh);
        writer.writeTechplot("./iphone/car2.dat", u);

        this.mesh = mesh;
        this.u = u;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//MeshReaderForTriangle r1 = new MeshReaderForTriangle("hand1.1.node","hand1.1.ele");
		//Mesh m = r1.read2DMesh();
		//Tools.plotFunction(m, "iphone", "hand.dat", X.M(Y));
		Hand hand = new Hand();
		hand.run();
	}

}
